<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>
        // apply 和call 的使用
        // 作用：可以改变this的指向
       //'use strict';
        // function f1(x,y){
        //     console.log('result: '+(x+y)+this)
        //     return 1000;
        // }
        // window.f1(10,20)

        // console.log('-------------------')
        // // f1 当成对象来使用的，对象可以调用方法
        // // apply 和 call 方法也是函数的调用方式
        // f1.apply();
        // f1.call();
        // // apply 和call 方法中 如果没用传入参数，或传入null，那么调用该方法的函数对象中的this就是默认的window

        // console.log('--------------------')
        //  f1.apply(null,[100,200])
        //  f1.call(null,100,200)
        //  //apply和call都可以让函数或者方法来调用，传入参数和函数自己调用的写法不一样，但是效果一样
        //   console.log('--------------------')
        //   var result1 =  f1.apply(null,[100,200])
        //   var result2 = f1.call(null,100,200)
        //   console.log(result1)
        //   console.log(result2)

        //   console.log('--------------------')
        //   function fun1(x,y){
        //       console.log('fun1:',(x+y),this.sex)
        //   }
        //   window.fun1(10,20)
        //   var obj = {
        //       sex:'male',
        //       age:20
        //   }
        //   fun1.apply(obj,[10,20])

        //   console.log('--------------------')

        //   function Person(age,sex,name){
        //       this.age = age
        //       this.sex = sex
        //       this.name = name
        //   }
        //   // 添加原型方法
        //   Person.prototype.sayHi = function(x,y){
        //       console.log('hello',this.name)
        //       return x+y;
        //   }

        //   var per = new Person(10,'male','小花')
        //   per.sayHi(10,20)

        //   console.log('--------------------')
        //   function Student(name,sex){
        //       this.name = name
        //       this.sex = sex
        //   }
        //   var stu = new Student('小明','male')
        //   var result3 =  per.sayHi.apply(stu,[10,20])
        //   var result4 =  per.sayHi.call(stu,10,20)
        //   console.log(result3 +' ----- '+result4)

        //   /*
        //     apply 和 call 都可以改变this的指向
        //     函数的调用，改变this的指向
        //   */
        //   function fun1(x,y){
        //       console.log((x+y)+'-----'+this)
        //       return '这是函数的返回值'
        //   }

        //   // apply和call 的调用
        //   var r1 = fun1.apply(null,[1,2]) //此时fun1中的this是window
        //   console.log(r1)
        //   var r2 = fun1.call(null,1,2) //此时fun1中的this是window
        //   console.log(r2)
        //   console.log('=============》')
        
        //   // 改变this的指向
        //   var obj = {
        //       sex:'male'
        //   }
        //   // 本来fun1是window对象的，但是传入obj之后，fun1函数此时就是obj对象的
        //   var r3 = fun1.apply(obj,[1,2]);//此时f1中的this是window
        //   console.log(r3)

        //   var r4 = fun1.call(obj,1,2) //此时fun1中的ths是
        //   console.log(r4)

          //方法改变this的指向

        //   function Person(age){
        //       this.age = age
        //   }
        //   Person.prototype.sayHi = function(x,y){
        //       console.log((x+y)+'====>'+this)
        //   }
        //   function Student(){

        //   }
        //   var per = new Person() // 实例对象
        //   var stu = new Student()// 实例对象

        //   per.sayHi.apply(stu,[10,20])
        //   per.sayHi.call(stu,10,20)

          //apply和call的使用方法
          /*
            apply的使用方法
            函数名称.apply(对象，【参数一，参数二，...】)
            方法名称.apply(对象，【参数一，参数二，...】)
            
            call的使用语法
            函数名称.call(对象，参数一，参数二，...)
            方法名称.call(对象，参数一，参数二，...)

            作用：改变this的指向
            不同的地方：参数传递的方式是不一样的

            只要是想使用别的对象的方法，并且希望这个方法是当前对象的，那么就可以使用apply或者是call的方法改变this的指向
          */
        function f1(){
            console.log(this)
        }

        // f1 是函数，也是对象
        console.dir(f1)
        // 对象调用方法，说明，该对象中有这个方法
        f1.apply()
        f1.call()

        function Person(){
            this.sayHi = function(){
                console.log('say hi...')
            };
        }
        Person.prototype.eat = function(){
            console.log('eat....')
        }
        var per = new Person()
        per.sayHi()
        per.eat()
        console.log(f1.__proto__ == Function.prototype)
        // 所有的函数都是Function的实例对象，
        console.log(Function.prototype)
        console.dir(Function)
        // apply和call实际上并不在函数这个实例对象中，而是在原型对象中

    </script>
    
</body>
</html>